<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ECMAScript基础(深入)之原型&原型链</title>
</head>
<body>
    <script>
        function Handphone(color){
            this.color = color;
            this.screen = '18:9';
        }
        console.log(Handphone.prototype); // 对象
        // 原型prototype其实是一个function的一个属性
        // 打印出来一看，结果它也是对象

        // Handphone.prototype.ram = '64G';
        // Handphone.prototype.screen = '16:9';

        // 开发写法
        Handphone.prototype = {
            ram: '64G',
            screen: '16:9'
        }

        var hp1 = new Handphone('red');

        console.log(hp1.ram);
        // 从上看出：
        // 所有被该构造函数构造出来的对象都可以继承原型上的属性和方法
        console.log(hp1.screen);
        // 从上看出：
        // 自己内部有该属性就不会访问原型上的属性了
        
        // 自己内部写死的值，每次实例化的时候都会走流程，这种情况产生冗余或耦合，
        // 因此，放在原型上继承就很好的解决了这个问题
        // 一般写死的，方法都会挂载到原型上

        function Test(){}

        Test.prototype.name = 'prototype';
        var test = new Test();

        console.log(test.name);

        // test.num = 1;
        // Test.prototype里没有num
        // 实例化对象不能增加，删除，修改原型(祖先)， 只能查

        // constructor -> 对应函数本身
        // __proto__ 是可以被修改的

        function Car(){}
        Car.prototype.name = 'Banz';
        var car = new Car();
        Car.prototype.name = 'Mazda'; // 直接修改原型对象上的name
        // 修改构造器的prototype属性，在实例后无法修改，在实例之前则能修改成功
        Car.prototype = {
            name: '未知'
        }

        console.log(car.name);

        // window return
        function test1(){
            var a = 0;
            function plus1(){
                a++;
                console.log(a);
            }
            return plus1;
        }

        var plus = new test1();
        plus();
        plus();
        plus();

        function test2(){
            var a = 0;
            function add(){
                a++;
                console.log(a, 'test2函数');
            }
            window.add = add;
        }
        test2();
        add();
        add();
        add();

        var add1 = (function(){
            var a = 1;
            function add(){
                a++;
                console.log(a, '立即执行');
            }
            return add;
            // window.add = add; // 也可这样执行
        })();

        add1();
        add1();
        add1();

        // 为了多个自执行忘记写分号报错
        ;(function(){})()
        ;(function(){})()
    </script>
</body>
</html>